﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using QS.Input;
using Microsoft.Xna.Framework.Graphics;

namespace QS
{
    class QFreeCamera : QCamera
    {
        private Vector3 cameraDirection = Vector3.Forward;
        private Vector3 cameraDelta = Vector3.Zero;

        private float mouseX = 0;
        private float mouseY = 0;

        public QFreeCamera(GraphicsDevice device) : base(device)
        {
            m_ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.01f, 1000f);
            updateLookAt();
            Position = new Vector3(0,3,0);
        }

        public Vector3 CameraDirection
        {
            get { return cameraDirection; }
        }

        public override void Update(GameTime time)
        {
            base.Update(time);
            Position += cameraDelta;
            cameraDelta = Vector3.Zero;

            MouseState mouseState = Mouse.GetState();
        }

        protected override void ProcessMouse(MouseState mouseState)
        {
            if (QMouseOperations.RightDown)
            {
                mouseState = QMouseOperations.MouseState;
                mouseX -= (QMouseOperations.PositionDelta.Y) / 400.0f;
                mouseY -= (QMouseOperations.PositionDelta.X) / 400.0f;
                cameraDirection = Vector3.Transform(Vector3.Forward, Matrix.CreateRotationX(mouseX) * Matrix.CreateRotationY(mouseY));
            }
        }

        protected override void ProcessKeyboard(List<Keys> keys)
        {
            if (QMouseOperations.RightDown)
            {
                if (keys.Contains(Keys.D))
                {
                    cameraDelta += Vector3.Transform(Vector3.Right / 10.0f, Matrix.CreateRotationY(mouseY));
                    keys.Remove(Keys.D);
                }

                if (keys.Contains(Keys.A))
                {
                    cameraDelta += Vector3.Transform(Vector3.Left / 10.0f, Matrix.CreateRotationY(mouseY));
                    keys.Remove(Keys.A);
                }

                if (keys.Contains(Keys.W))
                {
                    cameraDelta += Vector3.Transform(Vector3.Forward / 10.0f, Matrix.CreateRotationX(mouseX) * Matrix.CreateRotationY(mouseY));
                    keys.Remove(Keys.W);
                }

                if (keys.Contains(Keys.S))
                {
                    cameraDelta += Vector3.Transform(Vector3.Backward / 10.0f, Matrix.CreateRotationX(mouseX) * Matrix.CreateRotationY(mouseY));
                    keys.Remove(Keys.S);
                }

                if (keys.Contains(Keys.Q))
                {
                    cameraDelta += Vector3.Up / 10.0f;
                    keys.Remove(Keys.Q);
                }

                if (keys.Contains(Keys.Y))
                {
                    cameraDelta += Vector3.Down / 10.0f;
                    keys.Remove(Keys.Y);
                }
            }
            updateLookAt();
        }

        private void updateLookAt()
        {
            m_ViewMatrix = Matrix.CreateLookAt(Position, Position + cameraDirection, Vector3.Up);
        }
    }
}
